package com.liang.lollipop.lreader.drawable;

import android.animation.ValueAnimator;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.Xfermode;
import android.graphics.drawable.Drawable;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

/**
 * Created by Lollipop on 2017/09/09.
 * 蒙版的绘制Drawable
 */
public class MaskingDrawable extends Drawable implements ValueAnimator.AnimatorUpdateListener {

    private Path path;
    private int color = 0;
    private int targetColor = 0;
    private int nowColor = 0;
    private float corners = 0;
    private long duration = 500L;
    private ValueAnimator animator;
    private PorterDuffXfermode cornersXfermode =  new PorterDuffXfermode(PorterDuff.Mode.XOR);

    private Paint cornersPaint;

    public MaskingDrawable(int color) {
        this.color = color;
        this.nowColor = color;
        cornersPaint = new Paint();
        cornersPaint.setColor(Color.BLACK);
        cornersPaint.setAntiAlias(true);
        cornersPaint.setDither(true);
        path = new Path();
        animator = ValueAnimator.ofFloat(0,1);
        animator.setDuration(duration);
        animator.addUpdateListener(this);
    }

    @Override
    public void draw(@NonNull Canvas canvas) {
        Rect bounds = getBounds();
        canvas.drawRect(bounds,cornersPaint);
        cornersPaint.setXfermode(cornersXfermode);
        canvas.drawPath(path,cornersPaint);
        cornersPaint.setXfermode(null);
        canvas.drawColor(nowColor);

//        canvas.drawColor(Color.BLACK);
//        canvas.drawColor(nowColor);
//        canvas.save();
//        canvas.clipPath(path, Region.Op.XOR);
//        canvas.restore();
    }

    private void resetPath(){
        Rect bounds = getBounds();
        path.reset();
        path.addRoundRect(bounds.left,bounds.top,bounds.right,bounds.bottom,corners,corners, Path.Direction.CW);
        path.close();
        invalidateSelf();
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        resetPath();
    }

    @Override
    public void setAlpha(@IntRange(from = 0, to = 255) int alpha) {
    }

    @Override
    public void setColorFilter(@Nullable ColorFilter colorFilter) {
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSPARENT;
    }

    public void setColor(int color) {
        this.color = color;
        this.nowColor = color;
        invalidateSelf();
    }

    public void setCorners(float corners) {
        this.corners = corners;
        resetPath();
    }

    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        float value = (float) animation.getAnimatedValue();
        int a = (int) ((Color.alpha(targetColor)-Color.alpha(color))*value+Color.alpha(color));
        a = formatColor(a);

        int r = (int) ((Color.red(targetColor)-Color.red(color))*value+Color.red(color));
        r = formatColor(r);

        int g = (int) ((Color.green(targetColor)-Color.green(color))*value+Color.green(color));
        g = formatColor(g);

        int b = (int) ((Color.blue(targetColor)-Color.blue(color))*value+Color.blue(color));
        b = formatColor(b);

        nowColor = Color.argb(a,r,g,b);

        invalidateSelf();

    }

    public void smoothTo(int color){
        //如果新的颜色等于当前的目标颜色，那么任务这是无效操作
        if(color==targetColor)
            return;
        //将当前的颜色设置为起始颜色
        this.color = this.nowColor;
        //新的颜色设置为目标颜色
        this.targetColor = color;
        //取消历史动画
        animator.cancel();
        //启动新的动画
        animator.start();
    }

    public void setDuration(long duration) {
        this.duration = duration;
        animator.setDuration(duration);
    }

    private int formatColor(int color){
        if (color<0)
            return 0;
        if (color>255)
            return 255;
        return color;
    }

}


